/*
 * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.arialyy.aria.http;

import android.text.TextUtils;

import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.ProtocolType;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.SSLContextUtil;

import java.io.IOException;
import java.io.InputStream;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;

/**
 * Created by lyy on 2017/1/18. 链接帮助类
 */
public final class ConnectionHelp {
  private static final String TAG = "ConnectionHelp";
  private static final HttpLoggingInterceptor mLogInterceptor = new HttpLoggingInterceptor();

  /**
   * 处理url参数
   */
  public static URL handleUrl(String url, HttpTaskOption taskDelegate)
      throws MalformedURLException {
    Map<String, String> params = taskDelegate.getParams();

    ALog.e(TAG, String.format("设置参数，url: %s", url));
    if(params!=null) ALog.e(TAG, String.format("参数，header: %s", params.toString()) );
    if (params != null && taskDelegate.getRequestEnum() == RequestEnum.GET) {
      if (url.contains("?")) {
        ALog.e(TAG, String.format("设置参数失败，url中已经有?，url: %s", url));
        return new URL(CommonUtil.convertUrl(url));
      }
      StringBuilder sb = new StringBuilder();
      sb.append(url).append("?");
      Set<String> keys = params.keySet();
      for (String key : keys) {
        sb.append(key).append("=").append(URLEncoder.encode(params.get(key))).append("&");
      }
      String temp = sb.toString();
      temp = temp.substring(0, temp.length() - 1);
      return new URL(CommonUtil.convertUrl(temp));
    } else {
      return new URL(CommonUtil.convertUrl(url));
    }
  }

  /**
   * 转换HttpUrlConnect的inputStream流
   *
   * @return {@link GZIPInputStream}、{@link InflaterInputStream}
   * @throws IOException
   */
  public static InputStream convertInputStream(Response connection) throws IOException {
    String encoding = connection.header("Content-Encoding");
    ResponseBody body = connection.body();
    if(body == null){
      return null;
    }
    if (TextUtils.isEmpty(encoding)) {
      return body.byteStream();
    }
    if (encoding.contains("gzip")) {
      return new GZIPInputStream(body.byteStream());
    } else if (encoding.contains("deflate")) {
      return new InflaterInputStream(body.byteStream());
    } else {
      return body.byteStream();
    }
  }



  public static InputStream convertInputStreamConnect(HttpURLConnection connection) throws IOException {
    String encoding = connection.getHeaderField("Content-Encoding");
    if (TextUtils.isEmpty(encoding)) {
      return connection.getInputStream();
    }
    if (encoding.contains("gzip")) {
      return new GZIPInputStream(connection.getInputStream());
    } else if (encoding.contains("deflate")) {
      return new InflaterInputStream(connection.getInputStream());
    } else {
      return connection.getInputStream();
    }
  }

  public static HostnameVerifier getPermissiveHostnameVerifier() {
    return new HostnameVerifier() {
      @Override
      public boolean verify(String hostname, SSLSession session) {
        return true;
      }
    };
  }

  private static final TrustManager[] trustAllCerts = new TrustManager[] {
          new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {}
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {}
            @Override
            public X509Certificate[] getAcceptedIssuers() {
              return new X509Certificate[0];
            }
          }
  };

  public static OkHttpClient.Builder handleConnectionClient(HttpTaskOption taskDelegate) throws IOException {
    OkHttpClient.Builder builder;
    if (taskDelegate.getProxy() != null) {
      builder = new OkHttpClient.Builder().proxy(taskDelegate.getProxy());
    } else {
      builder = new OkHttpClient.Builder();
    }
//    mLogInterceptor.level(HttpLoggingInterceptor.Level.BODY);
//    builder.addInterceptor(mLogInterceptor);
    //设置信任证书
    AriaConfig config = AriaConfig.getInstance();
    builder.hostnameVerifier(getPermissiveHostnameVerifier());
    try {
      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
      // Create an ssl socket factory with our all-trusting manager
      SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
      builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return builder;
  }




  /**
   * request 设置头部参数
   */
    public static Request.Builder setConnectParamRequest(HttpTaskOption delegate, Request.Builder checkBuilder) {
      Request request= checkBuilder.build();
      Request.Builder builder= request.newBuilder();
      Set<String> keys = null;
      if (delegate.getHeaders() != null && delegate.getHeaders().size() > 0) {
        keys = delegate.getHeaders().keySet();
        for (String key : keys) {
          builder.addHeader(key, delegate.getHeaders().get(key));
        }
      }
       //Request 获取header
      if (request.header("Accept-Language") == null) {
        builder.addHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7");
      }
      if (request.header("Accept-Encoding") == null) {
        builder.addHeader("Accept-Encoding", "identity");
      }
      if (request.header("Accept-Charset") == null) {
        builder.addHeader("Accept-Charset", "UTF-8");
      }
      if (request.header("Connection") == null) {
        builder.addHeader("Connection", "Keep-Alive");
      }
      if (request.header("Charset") == null) {
        builder.addHeader("Charset", "UTF-8");
      }
      if (request.header("User-Agent") == null) {
        builder.addHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
      }
      if (request.header("Accept") == null) {
        StringBuilder accept = new StringBuilder();
        accept.append("image/gif, ")
                .append("image/jpeg, ")
                .append("image/pjpeg, ")
                .append("image/webp, ")
                .append("image/apng, ")
                .append("application/xml, ")
                .append("application/xaml+xml, ")
                .append("application/xhtml+xml, ")
                .append("application/x-shockwave-flash, ")
                .append("application/x-ms-xbap, ")
                .append("application/x-ms-application, ")
                .append("application/msword, ")
                .append("application/vnd.ms-excel, ")
                .append("application/vnd.ms-xpsdocument, ")
                .append("application/vnd.ms-powerpoint, ")
                .append("application/signed-exchange, ")
                .append("text/plain, ")
                .append("text/html, ")
                .append("*/*");
        builder.header("Accept", accept.toString());
      }
      CookieManager manager = delegate.getCookieManager();
      try {
        if (manager != null) {
          CookieStore store = manager.getCookieStore();
          if (store != null && store.getCookies().size() > 0) {
            builder.addHeader("Cookie", TextUtils.join(";", store.getCookies()));
          }
        }
      }catch (Exception e){
        e.printStackTrace();
        ALog.e(TAG, "cookie 设置 失败");
      }
      return builder;
    }

}
